package logv

import (
	"github.com/rs/zerolog"
)

// Hook 定义日志钩子接口
// 类似于 zerolog 的 Hook 接口，允许在日志写入前进行拦截和修改
type Hook interface {
	// Run 在日志事件写入前被调用
	// e: 日志事件
	// level: 日志级别
	// msg: 日志消息
	Run(e *zerolog.Event, level zerolog.Level, msg string)
}

// HookFunc 函数类型的钩子，方便创建简单的钩子
type HookFunc func(e *zerolog.Event, level zerolog.Level, msg string)

// Run 实现 Hook 接口
func (f HookFunc) Run(e *zerolog.Event, level zerolog.Level, msg string) {
	f(e, level, msg)
}

// LevelHook 按日志级别过滤的钩子
type LevelHook struct {
	hook   Hook
	levels []zerolog.Level
}

// NewLevelHook 创建按级别过滤的钩子
func NewLevelHook(levels []zerolog.Level, hook Hook) *LevelHook {
	return &LevelHook{
		hook:   hook,
		levels: levels,
	}
}

// Run 实现 Hook 接口，只在指定级别时执行钩子
func (h *LevelHook) Run(e *zerolog.Event, level zerolog.Level, msg string) {
	for _, l := range h.levels {
		if l == level {
			h.hook.Run(e, level, msg)
			return
		}
	}
}

// ConditionalHook 条件钩子，只在满足条件时执行
type ConditionalHook struct {
	hook      Hook
	condition func(level zerolog.Level, msg string) bool
}

// NewConditionalHook 创建条件钩子
func NewConditionalHook(condition func(level zerolog.Level, msg string) bool, hook Hook) *ConditionalHook {
	return &ConditionalHook{
		hook:      hook,
		condition: condition,
	}
}

// Run 实现 Hook 接口，只在条件满足时执行钩子
func (h *ConditionalHook) Run(e *zerolog.Event, level zerolog.Level, msg string) {
	if h.condition(level, msg) {
		h.hook.Run(e, level, msg)
	}
}

// CommonFieldsHook 公共字段钩子，为每个日志添加固定的公共字段
type CommonFieldsHook struct {
	fields map[string]interface{}
}

// NewCommonFieldsHook 创建公共字段钩子
func NewCommonFieldsHook(fields map[string]interface{}) *CommonFieldsHook {
	return &CommonFieldsHook{
		fields: fields,
	}
}

// Run 实现 Hook 接口，为每个日志添加公共字段
func (h *CommonFieldsHook) Run(e *zerolog.Event, level zerolog.Level, msg string) {
	for key, value := range h.fields {
		e.Interface(key, value)
	}
}

// AddField 添加公共字段
func (h *CommonFieldsHook) AddField(key string, value interface{}) {
	if h.fields == nil {
		h.fields = make(map[string]interface{})
	}
	h.fields[key] = value
}

// RemoveField 移除公共字段
func (h *CommonFieldsHook) RemoveField(key string) {
	if h.fields != nil {
		delete(h.fields, key)
	}
}

// SetFields 设置所有公共字段（替换现有字段）
func (h *CommonFieldsHook) SetFields(fields map[string]interface{}) {
	h.fields = fields
}

// GetFields 获取所有公共字段
func (h *CommonFieldsHook) GetFields() map[string]interface{} {
	result := make(map[string]interface{})
	for k, v := range h.fields {
		result[k] = v
	}
	return result
}